--- 'Eq', 'Ord' and 'Show' instances for tuples 4 .. 7
--- 'Functor' instances for tuples 4 .. 7
--- 'Semigroup' and 'Monoid' instances for tuples 2 .. 7
--- 'Monad' instances for Tuples 2 .. 7
package frege.data.Tuples where

import Data.Monoid



derive Eq (a, b, c, d);
derive Ord (a, b, c, d);
derive Show (a, b, c, d);

derive Eq (a, b, c, d, e);
derive Ord (a, b, c, d, e);
derive Show (a, b, c, d, e);

derive Eq (a, b, c, d, e, f);
derive Ord (a, b, c, d, e, f);
derive Show (a, b, c, d, e, f);

derive Eq (a, b, c, d, e, f, g);
derive Ord (a, b, c, d, e, f, g);
derive Show (a, b, c, d, e, f, g);



instance (Semigroup a, Semigroup b) => Semigroup (a, b) where
  (a, b) `mappend` (a', b') = (a <> a', b <> b')
instance (Monoid a, Monoid b) => Monoid (a, b) where
  mempty = (mempty, mempty) 

instance (Semigroup a, Semigroup b, Semigroup c) => Semigroup (a, b, c) where
  (a, b, c) `mappend` (a', b', c') = (a <> a', b <> b', c <> c')
instance (Monoid a, Monoid b, Monoid c) => Monoid (a, b, c) where
  mempty = (mempty, mempty, mempty) 

instance (Semigroup a, Semigroup b, Semigroup c, Semigroup d) => Semigroup (a, b, c, d) where
  (a, b, c, d) `mappend` (a', b', c', d') = (a <> a', b <> b', c <> c', d <> d')
instance (Monoid a, Monoid b, Monoid c, Monoid d) => Monoid (a, b, c, d) where
  mempty = (mempty, mempty, mempty, mempty) 
  
instance (Semigroup a, Semigroup b, Semigroup c, Semigroup d, Semigroup e) => Semigroup (a, b, c, d, e) where
  (a, b, c, d, e) `mappend` (a', b', c', d', e') = (a <> a', b <> b', c <> c', d <> d', e <> e')
instance (Monoid a, Monoid b, Monoid c, Monoid d, Monoid e) => Monoid (a, b, c, d, e) where
  mempty = (mempty, mempty, mempty, mempty, mempty)  
  
instance (Semigroup a, Semigroup b, Semigroup c, Semigroup d, Semigroup e, Semigroup f) => Semigroup (a, b, c, d, e, f) where
  (a, b, c, d, e, f) `mappend` (a', b', c', d', e', f') = (a <> a', b <> b', c <> c', d <> d', e <> e', f <> f')
instance (Monoid a, Monoid b, Monoid c, Monoid d, Monoid e, Monoid f) => Monoid (a, b, c, d, e, f) where
  mempty = (mempty, mempty, mempty, mempty, mempty, mempty)     
  
instance (Semigroup a, Semigroup b, Semigroup c, Semigroup d, Semigroup e, Semigroup f, Semigroup g) => Semigroup (a, b, c, d, e, f, g) where
  (a, b, c, d, e, f, g) `mappend` (a', b', c', d', e', f', g') = (a <> a', b <> b', c <> c', d <> d', e <> e', f <> f', g <> g')
instance (Monoid a, Monoid b, Monoid c, Monoid d, Monoid e, Monoid f, Monoid g) => Monoid (a, b, c, d, e, f, g) where
  mempty = (mempty, mempty, mempty, mempty, mempty, mempty, mempty)  
  


instance Functor ((,,,) a b c) where
  fmap fn (a, b, c, x) = (a, b, c, fn x)
instance Functor ((,,,,) a b c d) where
  fmap fn (a, b, c, d, x) = (a, b, c, d, fn x)  
instance Functor ((,,,,,) a b c d e) where
  fmap fn (a, b, c, d, e, x) = (a, b, c, d, e, fn x)  
instance Functor ((,,,,,,) a b c d e f) where
  fmap fn (a, b, c, d, e, f, x) = (a, b, c, d, e, f, fn x)  
  
  

instance (Monoid a) => Monad ((,) a) where
  pure x = (mempty, x)
  (a, fn) <*> (a', x) = (a <> a', fn x)
  (a, x) >>= fn = let (a', y) = fn x in (a <> a', y)
  
instance (Monoid a, Monoid b) => Monad ((,,) a b) where
  pure x = (mempty, mempty, x)
  (a, b, fn) <*> (a', b', x) = (a <> a', b <> b', fn x)
  (a, b, x) >>= fn = let (a', b', y) = fn x in (a <> a', b <> b', y)
  
instance (Monoid a, Monoid b, Monoid c) => Monad ((,,,) a b c) where
  pure x = (mempty, mempty, mempty, x)
  (a, b, c, fn) <*> (a', b', c', x) = (a <> a', b <> b', c <> c', fn x)
  (a, b, c, x) >>= fn = let (a', b', c', y) = fn x in (a <> a', b <> b', c <> c', y)       

instance (Monoid a, Monoid b, Monoid c, Monoid d) => Monad ((,,,,) a b c d) where
  pure x = (mempty, mempty, mempty, mempty, x)
  (a, b, c, d, fn) <*> (a', b', c', d', x) = (a <> a', b <> b', c <> c', d <> d', fn x)
  (a, b, c, d, x) >>= fn = let (a', b', c', d', y) = fn x in (a <> a', b <> b', c <> c', d <> d', y)       
  
instance (Monoid a, Monoid b, Monoid c, Monoid d, Monoid e) => Monad ((,,,,,) a b c d e) where
  pure x = (mempty, mempty, mempty, mempty, mempty, x)
  (a, b, c, d, e, fn) <*> (a', b', c', d', e', x) = (a <> a', b <> b', c <> c', d <> d', e <> e', fn x)
  (a, b, c, d, e, x) >>= fn = let (a', b', c', d', e', y) = fn x in (a <> a', b <> b', c <> c', d <> d', e <> e', y)       
  
instance (Monoid a, Monoid b, Monoid c, Monoid d, Monoid e, Monoid f) => Monad ((,,,,,,) a b c d e f) where
  pure x = (mempty, mempty, mempty, mempty, mempty, mempty, x)
  (a, b, c, d, e, f, fn) <*> (a', b', c', d', e', f', x) = (a <> a', b <> b', c <> c', d <> d', e <> e', f <> f', fn x)
  (a, b, c, d, e, f, x) >>= fn = let (a', b', c', d', e', f', y) = fn x in (a <> a', b <> b', c <> c', d <> d', e <> e', f <> f', y)